generic
   type cercle (<>) is private;
   type individu (<>) is private;
   type message (<>) is private;
   type mur (<>) is private;

   with function est_defini(M:mur;N:natural) return boolean is <>;
   with function auteur(M:mur;N:natural) return individu is <>;
   with function creer(I : individu) return mur is <>;
   with function ajouter(un_mur:mur;M : Message;Auteur : individu;N : Natural) return mur is <>;


   with function "=" (I1:individu;I2:individu)return boolean is <>;
   with function "<=" (I1:individu;I2:individu)return boolean is <>;
   with function "=" (I1:cercle;I2:cercle)return boolean is <>;
   with function "<=" (I1:cercle;I2:cercle)return boolean is <>;

package optimaltemps is

   type modele is private;

   function creer return modele;
   function inscrire(C0:modele; I1:individu) return modele;
   function est_inscrit(C0:modele;I1:individu) return boolean;
   function nombre_inscrit(C0:modele) return natural;
   function ieme_inscrit(C0:modele;I:Natural) return individu;
   function bloquer (C0:modele; I1,I2: individu) return modele;
   function debloquer(C0:modele;I1,I2: individu) return modele;
   function est_bloque(C0:modele; I1,I2:individu) return boolean;

   function ajouter_cercle(C0:modele; I1: individu; C1:cercle) return modele;
   function retirer_cercle(C0:modele; I1: individu; C1:cercle) return modele;
   function est_cercle_de(C0:modele;I1:individu;C1:cercle) return boolean;
   function ieme_cercle(C0:modele;I1:individu;I:natural) return cercle;

   function ajouter_membre(C0:modele; I1: individu; C1:cercle; I2: individu) return modele;
   function retirer_membre(C0:modele; I1: individu; C1:cercle; I2: individu) return modele;
   function poster(C0:modele;I1:individu;C1:cercle;T: message) return modele;
   function commenter(C0: modele; I1:individu; I:Natural; T: message) return modele;

   function nombre_cercle_de(C0:modele;I1:individu) return natural;
   function est_membre_de(C0:modele;I1:individu;C1:cercle;I2:individu) return boolean;
   function nombre_membre_de(C0:modele;I1:individu;C1:cercle)return natural;
   function ieme_membre(C0:modele;I1:individu;C1:cercle;I:natural)return individu;

   function consulter(C0:modele;I1:individu) return Mur;
   function nombre_post(C0:modele) return Natural;

private

   type liste_membre is array (positive range <>) of access individu;

   type un_cercle is record
      son_nom : access cercle;
      ses_membres : access liste_membre;
   end record;

   type liste_cercle is array (positive range <>) of access un_cercle;

   type un_individu is record
      son_nom : access individu;
      son_mur : access mur;
      ses_cercles : access liste_cercle;
      ses_bloques : access liste_membre;
   end record;

   type etat is array (positive range <>) of access un_individu;

   type modele is record
      nb_post : natural;
      acces_etat : access etat;
   end record;


end optimaltemps;


